#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
script usage:
    sudo python hosts.py
"""
import os


def fetch(url, outfile=None):
    """TODO: Error"""
    import urllib2
    # fetch html
    req = urllib2.Request(url)
    req.add_header('Accept-encoding', 'gzip')
    response = urllib2.urlopen(req)
    html = response.read()
    # uncompress gzip
    if response.info().get('Content-Encoding') == 'gzip':
        from StringIO import StringIO
        import gzip
        data = StringIO(html)
        file = gzip.GzipFile(fileobj=data)
        html = file.read()
    # output to a file
    if outfile:
        with open(outfile, 'w') as f:
            f.write(html)
    return html


def fetch_hosts(outfile='hosts.origin'):
    url = 'https://coding.net/u/scaffrey/p/hosts/git/raw/master/hosts-files/hosts'
    print('Get hosts from %s' % url)
    fetch(url, outfile)
    print('Save hosts to %s' % outfile)


def merge_hosts(src='/etc/hosts', dst='hosts.latest', origin='hosts.origin'):
    MODIFIED_START = '# Modified Hosts Start'
    MODIFIED_END = '# Modified Hosts End'
    with open(dst, 'w') as d:
        # copy outside of modified lines
        last_line = None
        with open(src, 'r') as s:
            modified = False
            for l in s:
                if modified:
                    if MODIFIED_END in l:
                        modified = False
                else:
                    if MODIFIED_START in l:
                        modified = True
                    else:
                        d.write(l)
                        last_line = l
        # copy inside of modified lines
        if last_line and last_line.rstrip():
            d.write(os.linesep)
        with open(origin, 'r') as o:
            modified = False
            for l in o:
                if modified:
                    if MODIFIED_END in l:
                        modified = False
                    d.write(l)
                else:
                    if MODIFIED_START in l:
                        modified = True
                        d.write(l)
                        # write timestamp
                        from datetime import datetime
                        d.write('# ')
                        d.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
                        d.write(os.linesep)


def update_hosts(src='/etc/hosts'):
    origin = 'hosts.origin'
    latest = 'hosts.latest'
    fetch_hosts(origin)
    print('Merge hosts to %s' % latest)
    merge_hosts(src=src, dst=latest, origin=origin)

    import shutil
    bak = src + '.bak'
    print('Backup %s to %s' % (src, bak))
    shutil.move(src, bak)
    print('Update %s' % src)
    shutil.move(latest, src)

    os.remove(origin)


if __name__ == '__main__':
    update_hosts()
